package com.qinggeng.project.system.service.impl;


import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.framework.config.mq.enums.MQTypeEnum;
import com.qinggeng.project.api.dto.DistributionPointDto;
import com.qinggeng.project.system.domain.*;
import com.qinggeng.project.system.mapper.*;

import com.qinggeng.project.system.service.IOrdersPointService;
import com.qinggeng.project.system.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * 订单配送点Service业务层处理
 *
 * @author qinggeng
 * @date 2020-06-17
 */
@Service
@Slf4j
public class OrdersPointServiceImpl implements IOrdersPointService
{
    private static final String LOCKID = "lockid";
    @Resource
    private RedissonClient redissonClient;

    @Resource
    private OrdersPointMapper ordersPointMapper;

    @Resource
    private DistributionPointMapper distributionPointMapper;

    @Resource
    private SinglePointSaleMapper singlePointSaleMapper;

    @Resource
    private PointSaleMessageRecordMapper pointSaleMessageRecordMapper;

    @Resource
    private ISysConfigService sysConfigService;

    @Resource
    private SumPointSaleMapper sumPointSaleMapper;

    /**
     * 查询订单配送点
     *
     * @param ordersPointId 订单配送点ID
     * @return 订单配送点
     */
    @Override
    public OrdersPoint selectOrdersPointById(Long ordersPointId)
    {
        return ordersPointMapper.selectOrdersPointById(ordersPointId);
    }

    /**
     * 查询订单配送点列表
     *
     * @param ordersPoint 订单配送点
     * @return 订单配送点
     */
    @Override
    public List<OrdersPoint> selectOrdersPointList(OrdersPoint ordersPoint)
    {
        return ordersPointMapper.selectOrdersPointList(ordersPoint);
    }

    /**
     * 新增订单配送点
     *
     *
     * @return 结果
     */
    @Override
    public int insertOrdersPoint(Long orderId,Long pointId)
    {

        DistributionPoint point = distributionPointMapper.selectDistributionPointById(pointId);
        OrdersPoint ordersPoint = new OrdersPoint(point);
        ordersPoint.setOrdersId(orderId);
        return ordersPointMapper.insertOrdersPoint(ordersPoint);
    }

    @Override
    public int insertOrdersPoint(OrdersPoint ordersPoint) {
        return ordersPointMapper.insertOrdersPoint(ordersPoint);
    }

    /**
     * 修改订单配送点
     *
     * @param ordersPoint 订单配送点
     * @return 结果
     */
    @Override
    public int updateOrdersPoint(OrdersPoint ordersPoint)
    {
        return ordersPointMapper.updateOrdersPoint(ordersPoint);
    }

    /**
     * 批量删除订单配送点
     *
     * @param ordersPointIds 需要删除的订单配送点ID
     * @return 结果
     */
    @Override
    public int deleteOrdersPointByIds(Long[] ordersPointIds)
    {
        return ordersPointMapper.deleteOrdersPointByIds(ordersPointIds);
    }

    /**
     * 删除订单配送点信息
     *
     * @param ordersPointId 订单配送点ID
     * @return 结果
     */
    @Override
    public int deleteOrdersPointById(Long ordersPointId)
    {
        return ordersPointMapper.deleteOrdersPointById(ordersPointId);
    }

    @Override
    public OrdersPoint selectOrdersPointByOrdersId(Long ordersId) {
        return ordersPointMapper.selectOrdersPointByOrdersId(ordersId);
    }

    @Override
    public OrdersPoint selectOrdersPointByUserId(Long userId) {
        return ordersPointMapper.selectOrdersPointByUserId(userId);
    }
    /**
     * 查询所有配送区域单个自提点一天的商品销量统计
     * @return
     */
    @Override
    public List<SinglePointSale> selectOrdersGoodsSaleList(String beforeTime, String afterTime) {
        return ordersPointMapper.selectOrdersGoodsSaleList(beforeTime,afterTime);
    }


    @Override
    @Transactional
    public boolean createPointSaleRecord() {
        try {
            //查询所有配送区域自提点一天的商品销量统计
            //昨天
            String pastDate = DateUtils.getPastDate(1);
            //今天
            String date = DateUtils.getDate();
            //具体时间
            String time = "22:00:00";
            String beforeTime = pastDate + " " + time;
            String afterTime = date + " " + time;

            List<SinglePointSale> singlePointSales = ordersPointMapper.selectOrdersGoodsSaleList(beforeTime,afterTime);
            if (singlePointSales == null || singlePointSales.size() == 0) {
                throw new CustomException("商品销量为空");
            }
            DistributionPoint distributionPoint = new DistributionPoint();
            distributionPoint.setIsOpen("10");
            //查询所有正在运营的自提点
            List<DistributionPoint> distributionPoints = distributionPointMapper.selectDistributionPointList(distributionPoint);
            if (distributionPoints == null || distributionPoints.size() == 0) {
                throw new CustomException("正在运营的自提点为空");
            }
            //查询所有配送区域单个自提点一天的商品销量统计
            //将各个自提点销售数据放入一个集合中
            List<List<SinglePointSale>> singleLists = new ArrayList<>();

            for (DistributionPoint point : distributionPoints) {
                //单个自提点销量放入集合中
                List<SinglePointSale> saleList = new ArrayList<>();
                for (SinglePointSale singlePointSale : singlePointSales) {
                    if (point.getId().equals(singlePointSale.getPointId())) {
                        saleList.add(singlePointSale);
                    }
                }
                singleLists.add(saleList);
            }

            //遍历总集合,合并单个自提点相同商品的销量
            List<SinglePointSale> singlePointSaleList = new ArrayList<>();
            for (List<SinglePointSale> list : singleLists) {
                List<SinglePointSale> newList = getNewSingleList(list);
                singlePointSaleList.addAll(newList);
            }
            singlePointSaleMapper.insertList(singlePointSaleList);

            //查询所有正在运行的分区
            String value = (String) sysConfigService.selectConfigByKey("sys.point.sortArea");
            if (value == null){
                throw new CustomException("配送区域为空");
            }
            List<String> sortAreas = JSONObject.parseArray(value, String.class);
            //将各个自提点销售数据放入一个集合中
            List<List<SumPointSale>> sumLists = new ArrayList<>();
            for (String sortArea : sortAreas) {
                //配送区域销量放入集合中
                List<SumPointSale> sumPointSales = new ArrayList<>();
                for (SinglePointSale singlePointSale : singlePointSales) {
                    if (sortArea.equals(singlePointSale.getSortArea())){
                        SumPointSale sumPointSale = new SumPointSale();
                        BeanUtils.copyProperties(singlePointSale,sumPointSale);
                        sumPointSales.add(sumPointSale);
                    }
                }
                sumLists.add(sumPointSales);
            }

            //遍历总集合,合并配送区域相同商品的销量
            List<SumPointSale> sumPointSaleList = new ArrayList<>();
            for (List<SumPointSale> sumList : sumLists) {
                List<SumPointSale> newList = getNewSumleList(sumList);
                sumPointSaleList.addAll(newList);
            }
            sumPointSaleMapper.insertList(sumPointSaleList);
            return true;
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            log.info("createPointSaleRecord{}",e.getMessage());
            return false;
        }
    }


    private static List<SinglePointSale> getNewSingleList(List<SinglePointSale> list) {
        HashMap<Long, SinglePointSale> tempMap = new HashMap<Long, SinglePointSale>();
        for (SinglePointSale singlePointSale : list) {
            Long temp = singlePointSale.getGoodsId();//获取编号
            //containsKey(Object key)该方法判断Map集合中是否包含指定的键名，如果包含返回true，不包含返回false
            //containsValue(Object value)该方法判断Map集合中是否包含指定的键值，如果包含返回true，不包含返回false
            singlePointSale.setPrint("0");
            if (tempMap.containsKey(temp)) {
                SinglePointSale p = new SinglePointSale();
                BeanUtils.copyProperties(singlePointSale, p);
                //合并相同id的SaleNum值
                p.setSaleNum(tempMap.get(temp).getSaleNum() + singlePointSale.getSaleNum());

                //HashMap不允许key重复，当有key重复时，前面key对应的value值会被覆盖
                tempMap.put(temp, p);
            } else {
                tempMap.put(temp, singlePointSale);
            }
        }

        //去除重复 编号id 的 list
        List<SinglePointSale> newList = new ArrayList<SinglePointSale>();
        for (Long temp : tempMap.keySet()) {
            newList.add(tempMap.get(temp));
        }
        return newList;
    }

    private static List<SumPointSale> getNewSumleList(List<SumPointSale> list) {
        HashMap<Long, SumPointSale> tempMap = new HashMap<Long, SumPointSale>();
        for (SumPointSale sumPointSale : list) {
            Long temp = sumPointSale.getGoodsId();//获取编号
            //containsKey(Object key)该方法判断Map集合中是否包含指定的键名，如果包含返回true，不包含返回false
            //containsValue(Object value)该方法判断Map集合中是否包含指定的键值，如果包含返回true，不包含返回false
            sumPointSale.setPrint("0");
            if (tempMap.containsKey(temp)) {
                SumPointSale p = new SumPointSale();
                BeanUtils.copyProperties(sumPointSale, p);
                //合并相同id的SaleNum值
                p.setSaleNum(tempMap.get(temp).getSaleNum() + sumPointSale.getSaleNum());

                //HashMap不允许key重复，当有key重复时，前面key对应的value值会被覆盖
                tempMap.put(temp, p);
            } else {
                tempMap.put(temp, sumPointSale);
            }
        }

        //去除重复 编号id 的 list
        List<SumPointSale> newList = new ArrayList<SumPointSale>();
        for (Long temp : tempMap.keySet()) {
            newList.add(tempMap.get(temp));
        }
        return newList;
    }
}
